#pragma once

#include "stdafx.h"

class Field;
class Game;

class Field
{
public:
	enum CellType
	{
		Empty,
		X,
		Done,
	};

	Field(Game *);
	int width() const;
	int height() const;
	void allocate(int, int);
	void fill(CellType);

	static char convert(CellType);

	void draw(HDC, int, int);
	void select(int, int);
	void onMouseDown(int, int);
	void again();
	void loadLevel(const char *);
	void loadPredefinedLevel(int);
	void nextLevel();
	void randomLevel();
	void generateRandomLevel();

private:
	Game *m_game;
	int m_width;
	int m_height;
	char *m_field;
	int m_sel_x;
	int m_sel_y;
	int m_size;
	int m_screen_width;
	int m_screen_height;
	int m_last_x;
	int m_last_y;

	int m_level_id;
	int m_level_x_count;
	int m_level_remains;

	void reset();
	void clearDone();

	CellType cell(int, int) const;
	void setCell(int, int, CellType);
	/** go() function does not check if the cell is CellType::X */
	bool go(int, int);
	bool validateRoute(const std::vector<std::pair<int, int> > &);
	int getMaxInDirection(int x, int y, int dx, int dy);
};

class Game
{
public:
	Game(HINSTANCE, HWND);
	Field *field() const;
	void onMouseDown(int, int);
	void onAgain();
	HWND wnd() const;
private:
	Field *m_field;
	HINSTANCE m_inst;
	HWND m_wnd;
};

extern Game *g_game;